#include "Complex.h"
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
Complex::Complex()
{
	(*this).re = 0.0;
	(*this).im = 0.0;
}
double Complex::getReal(void) const
{
	return this -> re;
}
void Complex::setReal(double real)
{
	this -> re = real;
}
double Complex::getImag(void) const
{
	return this -> im;
}
void Complex::setImag(double imag)
{
	this -> im = imag;
}
Complex::Complex(double x, double y)
{
	this -> re = x;
	this -> im = y;
}
Complex::Complex(const Complex *z)
{
	this -> re = z -> re;
	this -> im = z -> im;
}
Complex::Complex(const Complex &z)
{
	this -> re = z.re;
	this -> im = z.im;
}
Complex::~Complex()
{
	printf("\nThe object (%f, %f) has beed destroyed.", (*this).re, (*this).im);
}
Complex Complex::Sum(const Complex *z)
{
	double real = this -> re + z -> re;
	double imag = this -> im + z -> im;
	return Complex(real, imag);
}
Complex Complex::Sum(const Complex &z)
{
	double real = this -> re + z.re;
	double imag = this -> im + z.im;
	return Complex(real, imag);
}
Complex Complex::Sum(double d)
{
	double real = this -> re + d;
	double imag = this -> im + d;
	return Complex(real, imag);
}
Complex Complex::Substraction(const Complex *z)
{
	double real = this -> re - z -> re;
	double imag = this -> im - z -> im;
	return Complex(real, imag);
}
Complex Complex::Substraction(const Complex &z)
{
	double real = this -> re - z.re;
	double imag = this -> im - z.im;
	return Complex(real, imag);
}
Complex Complex::Substraction(double d)
{
	double real = this -> re - d;
	double imag = this -> re - d;
	return Complex(real, imag);
}
Complex Complex::Multiplication(const Complex *z)
{
	double real = this -> re * z -> re - this -> im * z -> im;
	double imag = this -> re * z -> im + z -> re * this -> im;
	return Complex(real, imag);
}
Complex Complex::Multiplication(const Complex &z)
{
	double real = this -> re * z.re - this -> im * z.im;
	double imag = this -> re * z.im + z.re * this -> im;
	return Complex(real, imag);
}
Complex Complex::Multiplication(double d)
{
	double real = this -> re * d;
	double imag = this -> re * d;
	return Complex(real, imag);
}
Complex Complex::Division(const Complex *z)
{
	if (z -> re == 0 && z -> im == 0)
	{
		printf("error: Division by zero!");
		exit(0);
	}
	else
	{
		double real = (this -> re * z -> re + this -> im * z -> im) / (z -> re * z -> re + z -> im * z -> im);	
		double imag = (this -> im * z -> re - this -> re * z -> im) / (z -> re * z -> re + z -> im * z -> im);
		return Complex(real, imag);
	}
}
Complex Complex::Division(const Complex &z)
{
	if (z.re == 0 && z.im == 0)
	{
		printf("error: Division by zero!");
		exit(0);
	}
	else
	{
		double real = (this -> re * z.re + this -> im * z.im) / (z.re * z.re + z.im * z.im);	
		double imag = (this -> im * z.re - this -> re * z.im) / (z.re * z.re + z.im * z.im);
		return Complex(real, imag);
	}
}
Complex Complex::Division(double d)
{
	if (d == 0)
	{	
		printf("error: Division by zero!");
		exit(0);
	}	
	else
	{
		double real = this -> re / d;
		double imag = this -> im / d;
		return Complex(real, imag);
	}
}
Complex Complex::Sqrt(void)
{
	double real = sqrt((sqrt(this -> re * this -> re + this -> im * this -> im) + this -> re) / 2);
	double imag = sqrt((sqrt(this -> re * this -> re + this -> im * this -> im) - this -> re) / 2);
	return Complex (real, imag);
}
Complex Complex::operator + (const Complex *z)
{
	double real = this -> re + z -> re;
	double imag = this -> im + z -> im;
	return Complex(real, imag);
}
Complex Complex::operator + (const Complex &z)
{
	double real = this -> re + z.re;
	double imag = this -> im + z.im;
	return Complex(real, imag);
}
Complex Complex::operator + (double d)
{
	double real = this -> re + d;
	return Complex(real, this -> im);
}
Complex operator + (double d, const Complex &z)
{
	double real = d + z.re;
	return Complex(real, z.im);
}
Complex Complex::operator - (const Complex *z)
{
	double real = this -> re - z -> re;
	double imag = this -> im - z -> im;
	return Complex(real, imag);
}
Complex Complex::operator - (const Complex &z)
{
	double real = this -> re - z.re;
	double imag = this -> im - z.im;
	return Complex(real, imag);
}
Complex Complex::operator - (double d)
{
	double real = this -> re - d;
	return Complex(real, this -> im);
}
Complex Complex::operator * (const Complex *z)
{
	double real = this -> re * z -> re - this -> im * z -> im;
	double imag = this -> re * z -> im + this -> im * z -> re;
	return Complex(real, imag);
}
Complex Complex::operator * (const Complex &z)
{
	double real = this -> re * z.re - this -> im * z.im;
	double imag = this -> re * z.im + this -> im * z.re;
	return Complex(real, imag);
}
Complex Complex::operator * (double d)
{
	double real = this -> re * d;
	double imag = this -> im * d;
	return Complex(real, imag);
}
Complex Complex::operator / (const Complex *z)
{
	if ((z -> re == 0) && (z -> im == 0))
		perror("ERROR: Division by zero!");
	double real = (this -> re * z -> re + this -> im * z -> im) / (z -> re * z -> re + z -> im * z -> im);
	double imag = (this -> im * z -> re - this -> re * z -> im) / (z -> re * z -> re + z -> im * z -> im);
	return Complex(real, imag);
}
Complex Complex::operator / (const Complex &z)
{
	if ((z.re == 0) && (z.im == 0))
		perror("ERROR: Division by zero!");
	double real = (this -> re * z.re + this -> im * z.im) / (z.re * z.re + z.im * z.im);
	double imag = (this -> im * z.re - this -> re * z.im) / (z.re * z.re + z.im * z.im);
	return Complex(real, imag);	
}
Complex Complex::operator / (double d)
{
	if (d == 0)
		perror("ERROR: Division by zero!");
	double real = this -> re / d;
	double imag = this -> im / d;
	return Complex(real, imag);
}
Complex Complex::operator = (const Complex *z)
{
	if ((this != z) && (z != NULL))
	{
		this -> re = z -> re;
		this -> im = z -> im;
	}
	else
		if (z != NULL)
			printf("Self assignment");
		else
			printf("NULL pointer to complex number.");
}
Complex Complex::operator = (const Complex &z)
{
	if (this != &z && &z != NULL)
	{
		this -> re = z.re;
		this -> im = z.im;
	}
	else
		if (&z != NULL)
			printf("Self assignment.");
		else
			printf("NULL pointer to complex number.");
	return *this;
}
Complex Complex::operator = (double d)
{
	this -> re = d;
	this -> im = 0;
	return *this;
}
bool Complex::operator == (const Complex *z)
{
	return this -> re == z -> re && this -> im == z -> im;
}
bool Complex::operator == (const Complex &z)
{
	return this -> re == z.re && this -> im == z.im;
}
bool Complex::operator == (double d)
{
	return this -> re == d && this -> im == 0;
}
bool Complex::operator < (const Complex *z)
{
	return sqrt(this -> re * this -> re + this -> im * this -> im) < sqrt(z -> re * z -> re + z -> im * z -> im);
}
bool Complex::operator < (const Complex &z)
{
	return sqrt(this -> re * this -> re + this -> im * this -> im) < sqrt(z.re * z.re + z.im * z.im);
}
bool Complex::operator < (double d)
{
	return sqrt(this -> re * this -> re + this -> im * this -> im) < sqrt(d * d);
}
Complex Complex::operator ++ (void)
{
	this -> re += 1;
	this -> im += 1;
	return *this;
}
Complex Complex::operator -- (void)
{
	this -> re -= 1;
	this -> im -= 1;
	return *this;
}
std::istream& operator >> (std::istream &in, Complex &c)
{
	in >> c.re >> c.im;
	return in;
}
std::ostream& operator << (std::ostream &out, Complex c)
{
	out << c.re << " " << c.im;
	return out;
}
using namespace std;
int main()
{
	printf("Everything is working fine.");
	return 0;
}